home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / sunrast.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  413 lines

  1. /*
  2.  * $Id: sunrast.c,v 0.91 1994/02/20 00:52:54 zhao Pre-Release $
  3.  *
  4.  *. This file is part of BIT shareware package. After the two weeks of
  5.  *  free evaluation period, you are encouraged (required) to register
  6.  *  your copy for a small registration fee, which is $35 for personal use
  7.  *  and $50 for commercial, government and institutional use.
  8.  *
  9.  *  Copyright(c) 1993, 1994 by T.C. Zhao.
  10.  *  All rights reserved.
  11.  *
  12.  *  Permission to use, copy, and distribute this software in its entirety
  13.  *  for non-commercial purposes is hereby granted, provided that the
  14.  *  above shareware and copyright notices and this permission notice
  15.  *  appear in all copies and their documentation.
  16.  *
  17.  *  This software may be modified for your own use, but modified versions
  18.  *  may not be distributed without prior consent of the author.
  19.  *
  20.  *  This software is provided "as is" without expressed or implied
  21.  *  warranty of any kind.
  22.  *
  23.  *.
  24.  *
  25.  * Sun Raster format support.
  26.  * For 8 bit images without a colormap, two choices are availble:
  27.  * one is to fake a colormap and use the data as the color index
  28.  * and the other is simply use the data as the gray intensity
  29.  * and respresent the image as T_GRAY(RGB).
  30.  */
  31.  
  32. #ifndef NO_SUNRAS
  33.  
  34. #if !defined(lint) && defined(F_ID)
  35. char *id_sr = "$Id: sunrast.c,v 0.91 1994/02/20 00:52:54 zhao Pre-Release $";
  36. #endif
  37.  
  38. #include "bit.h"
  39. #include "dmalloc.h"
  40.  
  41. /******************* Limits and defines ***************************/
  42.  
  43. /* supported format */
  44. #define RT_STANDARD       1
  45. #define RT_BYTE_ENCODED   2
  46. #define RT_FORMAT_RGB     3
  47.  
  48. /* supported maps */
  49. #define RMT_NONE          0
  50. #define RMT_EQUAL_RGB     1
  51.  
  52. /********************* local variables ********************/
  53.  
  54. static int ras_type, ras_depth, ras_length, ras_maplength;
  55.  
  56. /******************************************************************/
  57. int
  58. RAS_desc(IPTR im)
  59. {
  60.     FILE *fp = im->fp;
  61.     int i, ras_maptype;
  62.     CMPTR cm = im->cmap;
  63.  
  64.     /* skip 4 bytes signature */
  65.     (void) get4MSBF(fp);
  66.  
  67.     /* basic properties of the image */
  68.     im->w = get4MSBF(fp);
  69.     im->h = get4MSBF(fp);
  70.     ras_depth = get4MSBF(fp);
  71.     ras_length = get4MSBF(fp);
  72.     ras_type = get4MSBF(fp);
  73.     ras_maptype = get4MSBF(fp);
  74.     ras_maplength = get4MSBF(fp);
  75.  
  76. #ifdef MDEBUG
  77.     M_debug("RAS_desc", "w=%d h=%d depth=%d", im->w, im->h, ras_depth);
  78.     M_debug("RAS_desc", "type=%d length=%d", ras_type, ras_length);
  79.     M_debug("RAS_desc", "maptype=%d maplen=%d", ras_maptype, ras_maplength);
  80. #endif
  81.  
  82.     /* check */
  83.     if (ras_type != RT_STANDARD &&
  84.     ras_type != RT_BYTE_ENCODED &&
  85.     ras_type != RT_FORMAT_RGB)
  86.       {
  87.       Bark("RAS_desc", "Unknown/unsupported raster type: %d", ras_type);
  88.       return -1;
  89.       }
  90.  
  91.     /* check colormaps */
  92.     cm->colors = 0;
  93.     if (ras_maptype != RMT_EQUAL_RGB)
  94.       {
  95.       for (i = 0; i < ras_maplength; i++)
  96.           (void) getc(fp);
  97.       }
  98.     else
  99.       {
  100.       im->colors = cm->colors = ras_maplength / 3;
  101.       if (Badfread(cm->ct[0], 1, cm->colors, fp) ||
  102.           Badfread(cm->ct[1], 1, cm->colors, fp) ||
  103.           Badfread(cm->ct[2], 1, cm->colors, fp))
  104.         {
  105.         Bark("RAS_Desc", "Error reading colormap");
  106.         return -1;
  107.         }
  108.       }
  109.  
  110.     /* check image type */
  111.     switch (ras_depth)
  112.       {
  113.       case 1:            /* 2 colors */
  114.       im->colors = cm->colors = 2;
  115.       if (ras_maplength == 0 && ras_maptype == RMT_NONE)
  116.         {
  117.         im->type = T_BW;
  118.         cm->ct[0][0] = cm->ct[1][0] = cm->ct[2][0] = PCMAXV;
  119.         cm->ct[0][1] = cm->ct[1][1] = cm->ct[2][1] = 0;
  120.         }
  121.       else
  122.         {
  123.         im->type = T_CMAP;
  124.         }
  125.       break;
  126.  
  127.       case 8:            /* map, also could be grayscale */
  128.       if (ras_maplength == 0 && ras_maptype == RMT_NONE)
  129.         {
  130. #ifdef RAS_FAKE_MAP
  131.         im->type = T_GMAP;
  132.         im->colors = cm->colors = PCMAX;
  133.         for (i = 0; i <= PCMAXV; i++)
  134.             cm->ct[0][i] = cm->ct[1][i] = cm->ct[2][i] = i;
  135. #else
  136.         im->type = T_GRAY;
  137. #endif
  138.         }
  139.       else
  140.         {
  141.         im->type = T_CMAP;
  142.         }
  143.       break;
  144.  
  145.       case 24:
  146.       case 32:
  147.       im->type = T_RGBA;
  148.       break;
  149.  
  150.       default:
  151.       Bark("RAS_desc", "Bad depth: %d", ras_depth);
  152.       return -1;
  153.       }
  154.  
  155.     return 0;
  156. }
  157.  
  158. static long ras_rlines;
  159.  
  160. static int
  161. ras_decode(IPTR im, register unsigned char *pp)
  162. {
  163.     register int i, c, cnt;
  164.     register unsigned char *enc, *eh;
  165.     int err = (!(enc = eh = malloc(ras_length)) ||
  166.            Badfread(enc, 1, ras_length, im->fp));
  167.  
  168.     /* decode on the fly */
  169.     for (i = 0; i < ras_length;)
  170.       {
  171.       if ((c = *enc++) != 128)
  172.         {
  173.         *pp++ = c;
  174.         i++;
  175.         }
  176.       else
  177.         {            /* escape */
  178.         if ((cnt = 1 + *enc++) == 1)
  179.           {
  180.               *pp++ = 128;
  181.               i += 2;
  182.           }
  183.         else
  184.           {
  185.               for (c = *enc++; --cnt >= 0;)
  186.               *pp++ = c;
  187.               i += 3;
  188.           }
  189.         }
  190.       }
  191.     free(eh);
  192.     return err;
  193. }
  194.  
  195. int
  196. RAS_load(IPTR im)
  197. {
  198.     register unsigned char *pp, *ph;
  199.     register int i, h;
  200.     int linelen = (im->w * ras_depth + 15) / 16 * 2, err = 0;
  201.     void *mm;
  202.  
  203.     ras_rlines = progress_report("Loading Ras ...", im->h);
  204.     pp = ph = malloc(im->h * linelen);
  205.  
  206.     /* read in the raster */
  207.     switch (ras_type)
  208.       {
  209.       case RT_BYTE_ENCODED:
  210.       err = ras_decode(im, pp);
  211.       break;
  212.       default:
  213.       err = (Badfread(ph, 1, im->h * linelen, im->fp));
  214.       break;
  215.       }
  216.  
  217.     if (err)
  218.       {
  219.       Bark("RAS_load", "Error reading image");
  220.       return -1;
  221.       }
  222.  
  223.     /****** unpack to bit format *********/
  224.  
  225.     mm = im->mraster;
  226.     h = im->h;
  227.     for (pp = ph, i = 0; i < h; i++, pp = ph + i * linelen)
  228.       {
  229.       REPORT(i, ras_rlines);
  230.       switch (ras_depth)
  231.         {
  232.         case 24:
  233.         case 32:
  234.         {
  235.             register rgba_t *qs, *q = ((rgba_t **) mm)[h - 1 - i];
  236.             register int r, g, b;
  237.             if (ras_type == RT_FORMAT_RGB)
  238.               {
  239.               for (qs = q + im->w; q < qs; q++)
  240.                 {
  241.                 if (ras_depth == 32)
  242.                     pp++;
  243.                 r = *pp++;
  244.                 g = *pp++;
  245.                 b = *pp++;
  246.                 *q = Pack(r, g, b);
  247.                 }
  248.               }
  249.             else
  250.               {
  251.               for (qs = q + im->w; q < qs; q++)
  252.                 {
  253.                 if (ras_depth == 32)
  254.                     pp++;
  255.                 b = *pp++;
  256.                 g = *pp++;
  257.                 r = *pp++;
  258.                 *q = Pack(r, g, b);
  259.                 }
  260.               }
  261.         }
  262.         break;
  263.         case 8:
  264. #ifndef RAS_FAKE_MAP
  265.         if (ras_maplength == 0)
  266.           {
  267.               rgba_t *qs, *q = ((rgba_t **) mm)[h - 1 - i];
  268.               for (qs = q + im->w; q < qs; q++, pp++)
  269.               *q = Pack(*pp, *pp, *pp);
  270.           }
  271.         else
  272. #endif
  273.           {
  274.               register ci_t *qs, *q = ((ci_t **) mm)[h - 1 - i];
  275.               for (qs = q + im->w; q < qs; q++, pp++)
  276.               *q = *pp;
  277.           }
  278.         break;
  279.         case 1:
  280.         {
  281.             register ci_t *qs, *q = ((ci_t **) mm)[h - 1 - i];
  282.             register int mask;
  283.             for (mask = 0x80, qs = q + im->w; q < qs; q++)
  284.               {
  285.               if (!mask)
  286.                 {
  287.                 pp++;
  288.                 mask = 0x80;
  289.                 }
  290.               *q = (*pp & mask) ? 1 : 0;
  291.               mask >>= 1;
  292.               }
  293.         }
  294.         break;
  295.         }
  296.       }
  297.     free(ph);
  298.     remove_progress_report();
  299.     return 0;
  300. }
  301.  
  302. #define RAS_MAGIC 0x59a66a95
  303.  
  304. /* only write standard raster files */
  305.  
  306. int
  307. RAS_dump(IPTR im)
  308. {
  309.     FILE *fp = im->fp;
  310.     int linelen = (im->w * ras_depth + 15) / 16 * 2, i, h;
  311.     unsigned char *tmpline, *th;
  312.     CMPTR cm = im->cmap;
  313.  
  314.     ras_rlines = progress_report("Writing SunRas ...", im->h);
  315.     put4MSBF(RAS_MAGIC, fp);
  316.     put4MSBF(im->w, fp);
  317.     put4MSBF(im->h, fp);
  318.  
  319.     ras_depth = IS_RGBA(im) ? 24 : (IS_BW(im) ? 1 : 8);
  320.     put4MSBF(ras_depth, fp);
  321.     /* length is useless for standard type */
  322.     put4MSBF((im->w * im->h * ras_depth) / 8, fp);
  323.     put4MSBF(RT_STANDARD, fp);
  324.  
  325.     if (IS_CI(im))
  326.       {
  327.       put4MSBF(RMT_EQUAL_RGB, fp);
  328.       put4MSBF(cm->colors * 3, fp);
  329.       fwrite(cm->ct[0], 1, cm->colors, fp);
  330.       fwrite(cm->ct[1], 1, cm->colors, fp);
  331.       fwrite(cm->ct[2], 1, cm->colors, fp);
  332.       }
  333.     else
  334.       {
  335. #ifdef RAS_FAKE_MAP
  336.       cm->colors = PCMAX;
  337.       put4MSBF(RMT_EQUAL_RGB, fp);
  338.       put4MSBF(cm->colors * 3, fp);
  339.       for (i = 0; i < cm->colors; i++)
  340.           cm->ct[0][i] = cm->ct[1][i] = cm->ct[2][i] = i;
  341.       fwrite(cm->ct[0], 1, cm->colors, fp);
  342.       fwrite(cm->ct[1], 1, cm->colors, fp);
  343.       fwrite(cm->ct[2], 1, cm->colors, fp);
  344. #else
  345.       put4MSBF(RMT_NONE, fp);
  346.       put4MSBF(0, fp);
  347. #endif
  348.       }
  349.  
  350.     /* raster data */
  351.     linelen = (im->w * ras_depth + 15) / 16 * 2;
  352.     tmpline = th = malloc(linelen);
  353.     h = im->h;
  354.  
  355.     for (i = 0; i < h; i++, tmpline = th)
  356.       {
  357.       REPORT(i, ras_rlines);
  358.       if (ras_depth == 8)
  359.         {
  360.         if (IS_CI(im))
  361.           {
  362.               ci_t *ci = ((ci_t **) im->mraster)[h - 1 - i], *cis;
  363.               for (cis = ci + im->w; ci < cis; ci++)
  364.               *tmpline++ = *ci;
  365.           }
  366.         else
  367.           {        /* true grayscale */
  368.               rgba_t *p = ((rgba_t **) im->mraster)[h - 1 - i],
  369.                *ps;
  370.               for (ps = p + im->w; p < ps; p++)
  371.               *tmpline++ = get_R(*p);
  372.           }
  373.         }
  374.       else if (ras_depth == 24)
  375.         {
  376.         rgba_t *q = ((rgba_t **) im->mraster)[h - 1 - i], *qs;
  377.         register int r, g, b;
  378.         for (qs = q + im->w; q < qs; q++)
  379.           {
  380.               Unpack(*q, r, g, b);
  381.               *tmpline++ = b;
  382.               *tmpline++ = g;
  383.               *tmpline++ = r;
  384.           }
  385.         }
  386.       else if (ras_depth == 1)
  387.         {
  388.         ci_t *ci = ((ci_t **) im->mraster)[h - 1 - i], *cis;
  389.         register int k, bit;
  390.         for (k = bit = 0, cis = ci + im->w; ci < cis; ci++)
  391.           {
  392.               k = (k << 1) | *ci;
  393.               if (++bit == 8)
  394.             {
  395.                 *tmpline++ = k;
  396.                 k = bit = 0;
  397.             }
  398.           }
  399.         if (bit)
  400.           {        /* leftover */
  401.               k <<= (8 - bit);
  402.               *tmpline++ = k;
  403.           }
  404.         }
  405.       fwrite(th, 1, linelen, fp);
  406.       }
  407.     free(th);
  408.     remove_progress_report();
  409.     return fflush(fp);
  410. }
  411.  
  412. #endif /* NO_SUNRAS */
  413.